<html>
<head><meta charset="utf-8"><title>flat-merge iterators · t-compiler/help · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/index.html">t-compiler/help</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html">flat-merge iterators</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="222214481"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222214481" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> akraines <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222214481">(Jan 10 2021 at 09:38)</a>:</h4>
<p>Hi,</p>
<p>How can I do the equivilent of C#, where (in terms of ownership equivivilance) the function consumes the enumerable and returns a new expanded enumerable</p>
<div class="codehilite" data-code-language="C#"><pre><span></span><code><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="n">Merge</span><span class="p">(</span><span class="k">this</span> <span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;</span> <span class="k">base</span><span class="p">,</span> <span class="n">Func</span><span class="p">&lt;</span><span class="n">T</span><span class="p">,</span><span class="n">IEnumerable</span><span class="p">&lt;</span><span class="n">T</span><span class="p">&gt;&gt;</span> <span class="n">expand</span><span class="p">)</span> <span class="p">{</span>
   <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">b</span> <span class="k">in</span> <span class="k">base</span><span class="p">){</span>
    <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">s</span> <span class="k">in</span> <span class="n">expand</span><span class="p">(</span><span class="n">b</span><span class="p">)){</span>
       <span class="k">yield</span> <span class="k">return</span> <span class="n">s</span><span class="p">;</span>
    <span class="p">}</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div>
<p>I just used c# generator syntax b/c it describes the result, but I'm sure that there is a common iterator extension that supports this.</p>



<a name="222214558"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222214558" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222214558">(Jan 10 2021 at 09:40)</a>:</h4>
<p>are you looking for <code>flat_map</code>?</p>



<a name="222214560"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222214560" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222214560">(Jan 10 2021 at 09:41)</a>:</h4>
<p><a href="https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.flat_map">https://doc.rust-lang.org/nightly/std/iter/trait.Iterator.html#method.flat_map</a></p>



<a name="222214811"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222214811" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> scottmcm <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222214811">(Jan 10 2021 at 09:49)</a>:</h4>
<p>If you're looking for <a href="https://docs.microsoft.com/en-us/dotnet/api/system.linq.enumerable.selectmany?view=net-5.0#System_Linq_Enumerable_SelectMany__2_System_Collections_Generic_IEnumerable___0__System_Func___0_System_Collections_Generic_IEnumerable___1___"><code>Enumerable.SelectMany</code></a>, that's <code>Iterator::flat_map</code>.</p>



<a name="222215659"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222215659" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> akraines <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222215659">(Jan 10 2021 at 10:16)</a>:</h4>
<p>Yes, you are right, that is the same as flat_map. However I think the issue I was having was because I wanted to conditionally apply the flatmap.<br>
My code was something like this</p>
<div class="codehilite" data-code-language="Rust"><pre><span></span><code><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">values</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">generate_values</span><span class="p">(</span><span class="n">arr1</span><span class="p">)</span><span class="w"></span>
<span class="k">if</span><span class="w"> </span><span class="n">arr2</span><span class="p">.</span><span class="n">len</span><span class="p">()</span><span class="w"> </span><span class="o">&gt;</span><span class="mi">0</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w"> </span><span class="c1">//This is a simplified version. I was doing this in a loop, to recursively update values. ie. arr2 was actually a Vec&lt;Vec&lt;_&gt;&gt; and I was applying it for each inner vec in arr2.</span>
<span class="c1">//But I believe if the simple case works then the recursive case wil work just as well.</span>
<span class="w"> </span><span class="n">values</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">values</span><span class="p">.</span><span class="n">flat_map</span><span class="p">(</span><span class="o">|</span><span class="n">v</span><span class="o">|</span><span class="p">{</span><span class="n">generate_complex_values</span><span class="p">(</span><span class="n">arr2</span><span class="p">)});</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
<span class="n">do_something_with_final_version_of_values</span><span class="p">(</span><span class="n">values</span><span class="p">);</span><span class="w"></span>
</code></pre></div>
<p>However, it gave me errors about the type of values. (since Map struct != FlatMap struct)</p>



<a name="222216074"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222216074" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222216074">(Jan 10 2021 at 10:31)</a>:</h4>
<p>yeah, that's difficult cause each use of <code>flat_map</code> creates a new type as you said</p>



<a name="222216085"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222216085" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222216085">(Jan 10 2021 at 10:31)</a>:</h4>
<p>you can either use something like <code>Box&lt;dyn Iterator&gt;</code> to get around this</p>



<a name="222216141"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222216141" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222216141">(Jan 10 2021 at 10:32)</a>:</h4>
<p>or change it to <code>values = values.flat_map(|v| generate_complex_values(arr2)).collect();</code> and eagerly create a new collection every time</p>



<a name="222217746"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222217746" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> akraines <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222217746">(Jan 10 2021 at 11:17)</a>:</h4>
<p>I think a Box&lt;dyn Iterator&gt; would work. I'm just trying to avoid the unnexcessary collect()  in the middle, the extra inderirection is insignificant. <br>
So how to I make it into a Box&lt;dyn Iterator&gt;? Just wrap generate_values in a Box?</p>



<a name="222217793"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222217793" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> bjorn3 <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222217793">(Jan 10 2021 at 11:18)</a>:</h4>
<p><code>Box::new(generate_values)</code> or if it doesn't automatically cast to a trait object <code>Box::new(generate_values) as Box&lt;dyn Iterator&lt;Item = _&gt;&gt;</code>.</p>



<a name="222217983"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222217983" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222217983">(Jan 10 2021 at 11:24)</a>:</h4>
<p>i don't expect the collect in the middle to be that costly tbh</p>



<a name="222217993"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222217993" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> lcnr <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222217993">(Jan 10 2021 at 11:24)</a>:</h4>
<p>but would have to benchmark to know what's more efficient</p>



<a name="222219797"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222219797" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Joshua Nelson <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222219797">(Jan 10 2021 at 12:19)</a>:</h4>
<p>You could always write your own Iterator impl, I think that would let you avoid the collect</p>



<a name="222241520"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/182449-t-compiler/help/topic/flat-merge%20iterators/near/222241520" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> akraines <a href="https://rust-lang.github.io/zulip_archive/stream/182449-t-compiler/help/topic/flat-merge.20iterators.html#222241520">(Jan 10 2021 at 20:52)</a>:</h4>
<p>I followed up in the general section <a href="#narrow/stream/122651-general/topic/flat-merge.20iterators">https://rust-lang.zulipchat.com/#narrow/stream/122651-general/topic/flat-merge.20iterators</a> since I realised that this is t-compiler.<br>
Thank you very much for your help.</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>